﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Generic.Contract;
using Generic.Data.Manager;
using Contract.Business.Entity;
using Contract.Business.Filter;
using DataEntity;

namespace Contract.Data.Manager
{
    //Criado por : Gustavo
    //Data       : 10/25/2011 12:19:32 AM
    public class DMVenda : DMGeneric<BEVenda, FEVenda>
    {
        databaseDataContext dc;

        #region Override

        public override BEVenda Salvar(BEVenda entidade)
        {
            try
            {
                if (entidade.Codigo.Equals(0))
                    entidade.Codigo = Incluir(entidade);
                else
                    Alterar(entidade);

                return entidade;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public override void Excluir(BEVenda entidade)
        {
            try
            {
                dc = new databaseDataContext();

                var q = from r in dc.DEVendas
                        where
                            r.Codigo == entidade.Codigo
                        select r;

                DEVenda de = q.First();

                dc.DEVendas.DeleteOnSubmit(de);

                dc.SubmitChanges();
            }
            catch (Exception)
            {
                throw;
            }
        }

        public override BEVenda ObterEntidade(int codigo)
        {
            try
            {
                dc = new databaseDataContext();

                var q = from e in dc.DEVendas
                        where
                            e.Codigo == codigo
                        select e;

                return q.First().ConvertToBE(1);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public override List<BEVenda> ObterTodos(FEVenda filter)
        {
            try
            {
                dc = new databaseDataContext();

                var q = from e in dc.DEVendas
                        where
                        (
                            (((filter.CodigoCliente != null)
                            && (e.CodigoCliente == filter.CodigoCliente)) || (filter.CodigoCliente == null)) &&

                            (((filter.Telefone != null)
                            && (e.DECliente.TelResidencial == filter.Telefone)) || (filter.Telefone == null)) &&

                            (((filter.DataVendaMax != null)
                            && (e.DataVenda <= filter.DataVendaMax)) || (filter.DataVendaMax == null)) &&

                            (((filter.DataVendaMin != null)
                            && (e.DataVenda >= filter.DataVendaMin)) || (filter.DataVendaMin == null)) &&

                            (((filter.CodigoRegiaoEntrega != null)
                            && (e.CodigoRegiaoEntrega == filter.CodigoRegiaoEntrega)) || (filter.CodigoRegiaoEntrega == null)) &&

                            (((filter.ValorTotalMax != null)
                            && (e.ValorTotal <= filter.ValorTotalMax)) || (filter.ValorTotalMax == null)) &&

                            (((filter.ValorTotalMin != null)
                            && (e.ValorTotal >= filter.ValorTotalMin)) || (filter.ValorTotalMin == null)) &&

                            (((filter.ValorTaxaEntrega != null)
                            && (e.ValorTaxaEntrega == filter.ValorTaxaEntrega)) || (filter.ValorTaxaEntrega == null)) &&

                            (((filter.Enviada != null)
                            && (e.Enviada  == filter.Enviada)) || (filter.Enviada == null)) &&

                            (((filter.Codigo != null)
                            && (e.Codigo == filter.Codigo)) || (filter.Codigo == null))
                        )
                        select e;

                List<DEVenda> deVenda = q.ToList();

                List<BEVenda> retorno = new List<BEVenda>();

                foreach (DEVenda de in deVenda)
                    retorno.Add(de.ConvertToBE(1));

                return retorno;
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        #region Métodos Auxiliares

        public List<BEVendaItem> ObterItensVenda(int codigoVenda)
        {
            using (dc = new databaseDataContext())
            {
                var q = from e in dc.DEVendaItems
                        where e.CodigoVenda == codigoVenda
                        select e;

                List<DEVendaItem> deItens = q.ToList();

                List<BEVendaItem> retorno = new List<BEVendaItem>();

                foreach (DEVendaItem de in deItens)
                    retorno.Add(de.ConvertToBE(1));

                return retorno;
            }
        }

        public List<BEPagamento> ObterPagamentosVenda(int codigoVenda)
        {
            using (dc = new databaseDataContext())
            {
                var q = from e in dc.DEPagamentos
                        where e.CodigoVenda == codigoVenda
                        select e;

                List<DEPagamento> dePags = q.ToList();

                List<BEPagamento> retorno = new List<BEPagamento>();

                foreach (DEPagamento de in dePags)
                    retorno.Add(de.ConvertToBE(1));

                return retorno;
            }
        }

        private int Incluir(BEVenda entidade)
        {
            try
            {
                using (dc = new databaseDataContext())
                {

                    DEVenda de = new DEVenda();
                    de.ConvertFromBE(entidade);

                    dc.DEVendas.InsertOnSubmit(de);

                    dc.SubmitChanges();

                    return de.Codigo;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        private void Alterar(BEVenda entidade)
        {
            try
            {
                using (dc = new databaseDataContext())
                {

                    var q = from e in dc.DEVendas
                            where e.Codigo == entidade.Codigo
                            select e;

                    DEVenda de = q.First();

                    de.CodigoCliente = entidade.CodigoCliente;
                    de.CodigoEnderecoEntrega = entidade.CodigoEnderecoEntrega;
                    de.DataVenda = entidade.DataVenda;
                    de.Hora = entidade.Hora;
                    de.CodigoRegiaoEntrega = entidade.CodigoRegiaoEntrega;
                    de.ValorTotal = entidade.ValorTotal;
                    de.ValorTaxaEntrega = entidade.ValorTaxaEntrega;
                    de.ValorTroco = entidade.ValorTroco;
                    de.Observacao = entidade.Observacao;
                    de.Desconto = entidade.Desconto;
                    de.Acrescimo = entidade.Acrescimo;
                    de.Cancelado = entidade.Cancelada;
                    de.MotivoCancelamento = entidade.MotivoCancelamento;

                    dc.SubmitChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        public void SalvarEnviadas(List<BEVenda> entidades)
        {
            try
            {
                using (dc = new databaseDataContext())
                {
                    List<int> codigos = entidades.Select(e => e.Codigo).ToList();

                    var q = from e in dc.DEVendas
                            where codigos.Contains(e.Codigo)
                            select e;

                    List<DEVenda> vendas = q.ToList();
                    vendas.ForEach(v => v.Enviada = true);

                    dc.SubmitChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        public List<BEVenda> ObterNaoEnviadas()
        {
            try
            {
                List<BEVenda> vendas;
                using (dc = new databaseDataContext())
                {
                    var q = from e in dc.DEVendas
                            where
                                !e.Enviada
                            orderby e.Codigo ascending
                            select e;

                    List<DEVenda> deVendas = q.Take(100).ToList();

                    vendas = new List<BEVenda>();

                    foreach (DEVenda de in deVendas)
                        vendas.Add(de.ConvertToBE(1));
                }

                return vendas;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public void Cancelar(int codigo, string motivo)
        {
            try
            {
                using (dc = new databaseDataContext())
                {
                    DEVenda venda = dc.DEVendas.SingleOrDefault(q => q.Codigo == codigo);
                    if (venda == null)
                        throw new Exception("Venda não encontrada.");
                    else
                    {
                        venda.Cancelado = true;
                        venda.MotivoCancelamento = motivo;

                        dc.SubmitChanges();
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
    }
}
